package servlet;

import controller.ControllerAnnunciLocal;
import controller.ControllerCreazioneAnnuncioLocal;
import controller.ControllerMail;
import controller.ControllerRicercaLocal;
import eccezioni.AnnuncioChiusoException;
import eccezioni.CampoErratoException;
import eccezioni.UtenteNonCreatoreException;
import entity.Adesione;
import entity.Annuncio;
import entity.Articolo;
import entity.UtenteRegistrato;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import utilities.AnnuncioConDistanza;
import utilities.Utilities;

/**
 * Servlet che gestisce le richieste relative alla creazione di un annuncio
 * e in generale tutte le operazioni che può svolgere un utente sull'annuncio
 * da lui creato.
 * @author Ale
 */
public class CreazioneAnnuncioServlet extends HttpServlet {

    @EJB
    private ControllerCreazioneAnnuncioLocal controllerCreazioneAnnuncio;
    @EJB
    private ControllerMail controllerMail;
    @EJB
    private ControllerRicercaLocal controllerRicerca;
    @EJB
    private ControllerAnnunciLocal controllerAnnunci;

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String action = request.getParameter("action");

        if (action == null) {
            Utilities.errore("Nessuna action specificata alla CreazioneAnnuncioServlet", request, response);
        } else if (action.equals("mostraInserisciAnnuncio")) {
            mostraInserisciAnnuncio(request, response);
        } else if (action.equals("mostraModificaSpesaCreatorePopup")) {
            mostraModificaSpesaCreatorePopup(request, response);
        } else if (action.equals("inserisciAnnuncio")) {
            inserisciAnnuncio(request, response);
        } else if (action.equals("annuncioEsistente")) {
            annuncioEsistente(request, response);
        } else if (action.equals("accettaAdesione")) {
            accettaAdesione(request, response);
        } else if (action.equals("rifiutaAdesione")) {
            rifiutaAdesione(request, response);
        } else if (action.equals("accettaArticolo")) {
            accettaArticolo(request, response);
        } else if (action.equals("rifiutaArticolo")) {
            rifiutaArticolo(request, response);
        } else if (action.equals("rimuoviAnnuncio")) {
            rimuoviAnnuncio(request, response);
        } else if (action.equals("chiudiAnnuncio")) {
            chiudiAnnuncio(request, response);
        } else if (action.equals("modificaSpesaCreatore")) {
            modificaSpesaCreatore(request, response);
        }
    }

    private void mostraInserisciAnnuncio(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Utilities.forward("/inserisciAnnuncio.jsp", request, response);
    }

    private void mostraModificaSpesaCreatorePopup(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        long idAnnuncio = Long.parseLong(request.getParameter("idAnnuncio"));
        Annuncio annuncio = controllerAnnunci.getAnnuncio(idAnnuncio);
        request.setAttribute("annuncio", annuncio);
        Utilities.forward("/WEB-INF/jspf/modificaSpesaCreatore.jsp", request, response);
    }

    private void inserisciAnnuncio(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        UtenteRegistrato ur = Utilities.getUtenteLoggato(request);
        try {
            controllerCreazioneAnnuncio.inserisciAnnuncio(request.getParameter("url"), request.getParameter("chiusura"), request.getParameter("ordine"), request.getParameter("speseSped"), request.getParameter("indirizzo"), request.getParameter("spedGratis"), request.getParameter("spesaMinima"), request.getParameter("spesaCreatore"), ur);
        } catch (CampoErratoException cee) {
            request.setAttribute("errore", cee.getMessage());
            Utilities.forward("/inserisciAnnuncio.jsp", request, response);
            return;
        }
        request.setAttribute("utente", ur);
        request.setAttribute("giveFeedback", true);
        if (Utilities.getUtenteLoggatoLocal(request).getFacebookToken() != null) {
            //pubblico su bacheca Facebook
            String msg = "Ho pubblicato un annuncio per il sito " + request.getParameter("url") + " su Shipping Share. Anche tu vuoi acquistare dallo stesso sito? Condividiamo le spese di spedizione su Shipping Share! L'annuncio rimane aperto solo fino al " + request.getParameter("chiusura") + ".";
            String url = "/FbServlet?action=postFb&messaggio=" + msg;

            Utilities.include(url, request, response);
        }
        Utilities.include("/mostraProfilo.jsp", request, response);
    }

    //ajax
    private void annuncioEsistente(HttpServletRequest request, HttpServletResponse response) {
        String url = request.getParameter("url");
        List<AnnuncioConDistanza> list = controllerRicerca.cercaAperti(Utilities.getUtenteLoggato(request), url, Utilities.getUtenteLoggato(request).getIndirizzo().getDescrizione());

        response.setContentType("text/xml");
        response.setHeader("Cache-Control", "no-cache");
        try {
            response.getWriter().write("<numeroAnnunci>" + list.size() + "</numeroAnnunci>");
        } catch (IOException ex) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void accettaAdesione(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        long idAdesione = Long.parseLong(request.getParameter("idAdesione"));
        Adesione a = controllerAnnunci.getAdesione(idAdesione);
        try {
            controllerCreazioneAnnuncio.accettaAdesione(a, Utilities.getUtenteLoggato(request));
            UtenteRegistrato iscritto = a.getIscritto();
            UtenteRegistrato creatore = a.getAnnuncio().getCreatoreAnnuncio();
            controllerMail.sendMailAdesioneAccettata(iscritto, creatore, a);
            Utilities.mostraAnnunciCreati(request, response, a.getAnnuncio());
        } catch (UtenteNonCreatoreException ex) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void rifiutaAdesione(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        long idAdesione = Long.parseLong(request.getParameter("idAdesione"));
        Adesione a = controllerAnnunci.getAdesione(idAdesione);
        try {
            controllerCreazioneAnnuncio.rifiutaAdesione(a, Utilities.getUtenteLoggato(request));
            UtenteRegistrato iscritto = a.getIscritto();
            UtenteRegistrato creatore = a.getAnnuncio().getCreatoreAnnuncio();
            controllerMail.sendMailAdesioneRifiutata(iscritto, creatore, a);
        } catch (UtenteNonCreatoreException ex) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        }
        Utilities.mostraAnnunciCreati(request, response, a.getAnnuncio());
    }

    private void accettaArticolo(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        long idAdesione = Long.parseLong(request.getParameter("idAdesione"));
        long idArticolo = Long.parseLong(request.getParameter("idArticolo"));
        Adesione a = controllerAnnunci.getAdesione(idAdesione);
        Articolo art = controllerAnnunci.getArticolo(idArticolo);
        try {
            controllerCreazioneAnnuncio.accettaArticolo(a, art, Utilities.getUtenteLoggato(request));
            boolean noInSospeso = true;
            for (Articolo articolo : a.getArticoli()) {
                if (articolo.getStato() == Articolo.Stato.IN_SOSPESO) {
                    noInSospeso = false;
                }
            }
            if (noInSospeso) {
                //notifico l'iscritto
                UtenteRegistrato iscritto = a.getIscritto();
                UtenteRegistrato creatore = a.getAnnuncio().getCreatoreAnnuncio();
                controllerMail.sendMailArticoliControllati(iscritto, creatore, a);
            }
        } catch (UtenteNonCreatoreException ex) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        }
        Utilities.mostraAnnunciCreati(request, response, a.getAnnuncio());
    }

    private void rifiutaArticolo(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        long idAdesione = Long.parseLong(request.getParameter("idAdesione"));
        long idArticolo = Long.parseLong(request.getParameter("idArticolo"));
        Adesione a = controllerAnnunci.getAdesione(idAdesione);
        Articolo art = controllerAnnunci.getArticolo(idArticolo);
        try {
            controllerCreazioneAnnuncio.rifiutaArticolo(a, art, Utilities.getUtenteLoggato(request));
            boolean inSospeso = false;
            for (Articolo articolo : a.getArticoli()) {
                if (articolo.getStato() == Articolo.Stato.IN_SOSPESO) {
                    inSospeso = true;
                }
            }
            if (!inSospeso) {
                //notifico l'iscritto
                UtenteRegistrato iscritto = a.getIscritto();
                UtenteRegistrato creatore = a.getAnnuncio().getCreatoreAnnuncio();
                controllerMail.sendMailArticoliControllati(iscritto, creatore, a);
            }
        } catch (UtenteNonCreatoreException ex) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        }
        Utilities.mostraAnnunciCreati(request, response, a.getAnnuncio());
    }

    private void rimuoviAnnuncio(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        long idAnnuncio = Long.parseLong(request.getParameter("idAnnuncio"));
        Annuncio a = controllerAnnunci.getAnnuncio(idAnnuncio);

        UtenteRegistrato creatore = a.getCreatoreAnnuncio();

        /* recupero gli iscritti prima di cancellare tutte le adesioni */
        List<UtenteRegistrato> iscritti = new LinkedList<UtenteRegistrato>();
        for (Adesione ad : a.getAdesioni()) {
            UtenteRegistrato iscritto = ad.getIscritto();
            iscritti.add(iscritto);
        }

        try {
            controllerCreazioneAnnuncio.rimuoviAnnuncio(a, Utilities.getUtenteLoggato(request));
            for (UtenteRegistrato iscritto : iscritti) {
                controllerMail.sendMailAnnuncioRimossoAIscritto(creatore, iscritto, a.getSito());
            }
            Utilities.mostraAnnunciCreati(request, response, null);
        } catch (UtenteNonCreatoreException ex) {
            Utilities.errore(ex.getMessage(), request, response);
        } catch (AnnuncioChiusoException ex) {
            Utilities.errore(ex.getMessage(), request, response);
        }


    }

    private void chiudiAnnuncio(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        long idAnnuncio = Long.parseLong(request.getParameter("idAnnuncio"));
        Annuncio a = controllerAnnunci.getAnnuncio(idAnnuncio);

        UtenteRegistrato creatore = a.getCreatoreAnnuncio();

        /* recupero gli iscritti*/
        List<UtenteRegistrato> iscritti = new LinkedList<UtenteRegistrato>();
        for (Adesione ad : a.getAdesioni()) {
            UtenteRegistrato iscritto = ad.getIscritto();
            iscritti.add(iscritto);
        }

        try {
            controllerCreazioneAnnuncio.chiudiAnnuncio(a, Utilities.getUtenteLoggato(request));
            for (UtenteRegistrato iscritto : iscritti) {
                controllerMail.sendMailAnnuncioChiuso(creatore, iscritto, a);
            }
            Utilities.mostraAnnunciCreati(request, response, null);
        } catch (UtenteNonCreatoreException ex) {
            Utilities.errore(ex.getMessage(), request, response);
        } catch (AnnuncioChiusoException ex) {
            Utilities.errore(ex.getMessage(), request, response);
        }
    }

    private void modificaSpesaCreatore(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        long idAnnuncio = Long.parseLong(request.getParameter("idAnnuncio"));
        Annuncio a = controllerAnnunci.getAnnuncio(idAnnuncio);

        String spesa = request.getParameter("spesa");

        try {
            controllerCreazioneAnnuncio.modificaSpesaCreatore(Utilities.getUtenteLoggato(request), a, spesa);
            Utilities.mostraAnnunciCreati(request, response, a);
        } catch (UtenteNonCreatoreException unce) {
            Utilities.errore(unce.getMessage(), request, response);
        } catch (CampoErratoException cee) {
            request.setAttribute("errore", cee.getMessage());
            Utilities.mostraAnnunciCreati(request, response, a);
        } catch (AnnuncioChiusoException ace){
            Utilities.errore(ace.getMessage(), request, response);
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
    
}
